/**
 * 
 */
package com.huaqin.expression;

import com.huaqin.expression.BaseDataMeta.DataType;
import com.huaqin.expression.IOperatorExecution.Operator;

/**
 * 表达式解析词元对象
 */
public class ExpressionToken {
	

	//词元的语法类型
	public enum ETokenType{
		//常量
		ETOKEN_TYPE_CONSTANT ,
		//变量
		ETOKEN_TYPE_VARIABLE ,	
		//操作符
		ETOKEN_TYPE_OPERATOR ,
		//函数
		ETOKEN_TYPE_FUNCTION ,
		//分隔符
		ETOKEN_TYPE_SPLITOR ,
		;
	}
	
	//Token的词元类型：常量，变量，操作符，函数，分割符
	private ETokenType tokenType ;
	
	//当TokenType = ETOKEN_TYPE_CONSTANT 时,constant存储常量描述
	private Constant constant;
	
	//当TokenType = ETOKEN_TYPE_OPERATOR 时, operator存储操做符描述
	private Operator operator;
	
	//存储字符描述
	private String tokenText ;
	
	//词元在表达式中的起始位置
	private int startPosition = -1;
	
	public static ExpressionToken createConstantToken(DataType dataType , Object dataValue){
		ExpressionToken instance = new ExpressionToken();
		instance.constant = new Constant(dataType , dataValue);
		instance.tokenType = ETokenType.ETOKEN_TYPE_CONSTANT;
		if(dataValue != null){
			instance.tokenText=  instance.constant.getDataValueText();
		}
		return instance;
	}
	
	public static ExpressionToken createConstantToken(Constant constant){
		if(constant == null){
			throw new IllegalArgumentException("非法参数异常：常量为null" );
		}
		ExpressionToken instance = new ExpressionToken();
		instance.constant = constant;
		instance.tokenType = ETokenType.ETOKEN_TYPE_CONSTANT;
		if(constant.getDataValue() != null){
			instance.tokenText=  constant.getDataValueText();
		}
		return instance;
	}
	
	public static ExpressionToken createReference(Reference ref){
		ExpressionToken instance = new ExpressionToken();
		instance.constant = new Constant(ref);
		instance.tokenType = ETokenType.ETOKEN_TYPE_CONSTANT;
		if(ref != null){
			instance.tokenText=  instance.constant.getDataValueText();
		}
		return instance;
	}	
	
	public static ExpressionToken createFunctionToken(String functionName){
		if(functionName == null){
			throw new IllegalArgumentException("非法参数：函数名称为空");
		}
		ExpressionToken instance = new ExpressionToken();
		instance.tokenText = functionName;
		instance.tokenType = ETokenType.ETOKEN_TYPE_FUNCTION;
		return instance;
	}
	
	public static ExpressionToken createOperatorToken(Operator operator){
		if(operator == null){
			throw new IllegalArgumentException("非法参数：操作符为空");
		}
		ExpressionToken instance = new ExpressionToken();
		instance.operator = operator;
		instance.tokenText = operator.getToken();
		instance.tokenType = ETokenType.ETOKEN_TYPE_OPERATOR;
		return instance;
	}
	
	public static ExpressionToken createSplitorToken(String splitorText){
		if(splitorText == null){
			throw new IllegalArgumentException("非法参数：分隔符为空");
		}
		ExpressionToken instance = new ExpressionToken();
		instance.tokenText = splitorText;
		instance.tokenType = ETokenType.ETOKEN_TYPE_SPLITOR;
		return instance;
	}
	
	/**
	 * 私有构造函数
	 * @param tokenText
	 * @param tokenType
	 * @param dataType
	 */
	private ExpressionToken(){
	}
	
	/**
	 * 获取Token的词元类型
	 * @return
	 */
	public ETokenType getTokenType() {
		return tokenType;
	}

	
	/**
	 * 获取Token的常量描述
	 * @return
	 */
	public Constant getConstant(){
		return this.constant;
	}

	/**
	 * 获取Token的操作符类型值
	 * @return
	 */
	public Operator getOperator(){
		return this.operator;
	}
	
	/**
	 * 获取Token的方法名类型值
	 * @return
	 */
	public String getFunctionName(){
		//TODO 考虑后期直接return Method
		return this.tokenText;
	}
	
	/**
	 * 获取Token的分隔符类型值
	 * @return
	 */	
	public String getSplitor(){
		return this.tokenText;
	}

	public int getStartPosition() {
		return startPosition;
	}

	public void setStartPosition(int startPosition) {
		this.startPosition = startPosition;
	}
	
	@Override
	public String toString(){
		return tokenText;
	}
	
	/**
	 * 表达式字符窜词元处理辅助类
	 * 这个类考虑到性能因素，对词元类型，只进行简单辨别，词元的完整性依赖于RPN已经经过合法校验
	 */
	public static class ExpressionTokenHelper {
		
		
		public static boolean isNull(String s){
			return "null".equals(s);
		}
		
		public static boolean isBoolean(String s){
			return  "true".equals(s) || "false".equals(s) ;
		}
		
		public static boolean isString(String s){
			if(s != null && s.length() > 1){
				return (s.charAt(0) == '"');
			}else {
				return false;
			}		
		
		}
		
		/**
		 * 是否是分隔符词元
		 * @param s
		 * @return
		 */
		public static boolean isSplitor(String s){
			return ",".equals(s) || "(".equals(s) || ")".equals(s); 
		}
			
		/**
		 * 是否是操作符
		 * @param s
		 * @return
		 */
		public static boolean isOperator(String s){
			if(s != null){
				try{
					Operator.valueOf(s);
					return true;
				}catch(IllegalArgumentException e){
					return false;
				}
			}else {
				return false;
			}
		}
	}
}
